﻿// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/SliderShader" {
	Properties {
		defaultTransitionSize ("Transition Size", Float) = 0.011
		defaultBorderSize ("Border Size", Float) = 0.11
		outerShadowSize ("Shadow Size", Float) = 0.08

		[MaterialToggle] style ("osu!next Style", Float) = 0
		bodyColorSaturation("Body Color Saturation", Float) = 1
		bodyAlphaMultiplier("Body Alpha Multiplier", Float) = 1
		borderSizeMultiplier("Border Size Multiplier", Float) = 1
		colBorder("Border Color", Color) = (1,1,1,1)
		colBody("Body Color", Color) = (1,0,0,1)

		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend Mode", Float) = 1
        [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend Mode", Float) = 1
        [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest ("ZTest", Float) = 1
	}

    SubShader { 
        Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
        LOD 200

        Pass
        {
        	Cull Off
			Lighting Off
			ZWrite On
//			Offset -1, -1
			Fog { Mode Off }
//			ColorMask RGB
//			Blend [_SrcBlend] [_DstBlend]
//			ZTest [_ZTest]

			CGPROGRAM
			// Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct appdata members vertex,texcoord)
			//#pragma excluderenderers d3d11

			#pragma vertex vert 
			#pragma fragment frag

			// Use shader model 3.0 target, to get nicer looking lighting
			#pragma target 3.0

			#include "UnityCG.cginc"

			float defaultTransitionSize;
			float defaultBorderSize;
			float outerShadowSize;
			float style;

			float bodyColorSaturation;
			float bodyAlphaMultiplier;
			float borderSizeMultiplier;
			fixed4 colBorder;
			fixed4 colBody;

			sampler2D _CameraDepthTexture;  
            float4 _CameraDepthTexture_ST;  

	        // vertex shader inputs
	        struct appdata
	        {
	            float4 vertex : POSITION; // vertex position
	            float2 texcoord : TEXCOORD0; // texture coordinate
	        };

	        // vertex shader outputs ("vertex to fragment")
	        struct v2f
	        {
	            float2 uv : TEXCOORD0; // texture coordinate
	            float4 pos : SV_POSITION; // clip space position
	        };

	        // vertex shader
	        v2f vert (appdata v)
	        {
	            v2f o;
	            o.pos = UnityObjectToClipPos(v.vertex);
	            o.uv = TRANSFORM_TEX(v.texcoord, _CameraDepthTexture);
	            return o;
	        }

			float4 getInnerBodyColor(in float4 bodyColor)
			{
				float brightnessMultiplier = 0.25;
				bodyColor.r = min(1.0, bodyColor.r * (1.0 + 0.5 * brightnessMultiplier) + brightnessMultiplier);
				bodyColor.g = min(1.0, bodyColor.g * (1.0 + 0.5 * brightnessMultiplier) + brightnessMultiplier);
				bodyColor.b = min(1.0, bodyColor.b * (1.0 + 0.5 * brightnessMultiplier) + brightnessMultiplier);
				return float4(bodyColor);
			}

			float4 getOuterBodyColor(in float4 bodyColor)
			{
				float darknessMultiplier = 0.1;
				bodyColor.r = min(1.0, bodyColor.r / (1.0 + darknessMultiplier));
				bodyColor.g = min(1.0, bodyColor.g / (1.0 + darknessMultiplier));
				bodyColor.b = min(1.0, bodyColor.b / (1.0 + darknessMultiplier));
				return float4(bodyColor);
			}

			float4 frag ( v2f i ) : SV_Target
			{
				float borderSize = defaultBorderSize * borderSizeMultiplier;
				const float transitionSize = defaultTransitionSize;

				// output var
				float4 outcolor = float4(0.0, 0.0, 0.0, 0.0);
				
				// dynamic color calculations
				float4 borderColor = float4(colBorder.x, colBorder.y, colBorder.z, 1.0);
				float4 bodyColor = float4(colBody.x, colBody.y, colBody.z, 0.7 * bodyAlphaMultiplier);
				float4 outerShadowColor = float4(0, 0, 0, 0.25);
				float4 innerBodyColor = getInnerBodyColor(bodyColor);
				float4 outerBodyColor = getOuterBodyColor(bodyColor);
				
				innerBodyColor.rgb *= bodyColorSaturation;
				outerBodyColor.rgb *= bodyColorSaturation;
				
				// osu!next style color modifications
				if (style == 1)
				{
					outerBodyColor.rgb = bodyColor.rgb * bodyColorSaturation;
					outerBodyColor.a = 1.0 * bodyAlphaMultiplier;
					innerBodyColor.rgb = bodyColor.rgb * 0.5 * bodyColorSaturation;
					innerBodyColor.a = 0.0;
				}
				
				// a bit of a hack, but better than rough edges
				if (borderSizeMultiplier < 0.01)
					borderColor = outerShadowColor;
				
				// conditional variant
				if (i.uv.y < outerShadowSize - transitionSize) // just shadow
				{
					float delta = i.uv.y / (outerShadowSize - transitionSize);
					outcolor = lerp(float4(0, 0, 0, 0), outerShadowColor, delta);
				}
				if (i.uv.y > outerShadowSize - transitionSize && i.uv.y < outerShadowSize + transitionSize) // shadow + border
				{
					float delta = (i.uv.y - outerShadowSize + transitionSize) / (2.0 * transitionSize);
					outcolor = lerp(outerShadowColor, borderColor, delta);
				}
				if (i.uv.y > outerShadowSize + transitionSize && i.uv.y < outerShadowSize + borderSize - transitionSize) // just border
				{
					outcolor = borderColor;
				}
				if (i.uv.y > outerShadowSize + borderSize - transitionSize && i.uv.y < outerShadowSize + borderSize + transitionSize) // border + outer body
				{
					float delta = (i.uv.y - outerShadowSize - borderSize + transitionSize) / (2.0 * transitionSize);
					outcolor = lerp(borderColor, outerBodyColor, delta);
				}
				if (i.uv.y > outerShadowSize + borderSize + transitionSize) // outer body + inner body
				{	
					float size = (outerShadowSize + borderSize + transitionSize);
					float delta = ((i.uv.y - size) / (1.0-size));
					outcolor = lerp(outerBodyColor, innerBodyColor, delta);
				}

				return outcolor;
			}
			ENDCG
		}
	}
}